
#include "debug.h"
#include "CryptInterface.h"

CryptInterface::CryptInterface()
{
   const int status = cryptInit();

   if (status != CRYPT_OK)
   {
      errprint("cryptlib failed to initialise!");
   }
}

CryptInterface::~CryptInterface()
{
   cryptEnd();
}

int CryptInterface::GetErrorDetailCert(CRYPT_CERTIFICATE cert)
{
   CRYPT_ATTRIBUTE_TYPE errorLocus;
   CRYPT_ERRTYPE_TYPE errorType;
   cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&errorLocus);
   cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errorType);
   printf("errorlocus %d errortype %d\n", errorLocus, errorType);
   // etc.. I don't think it's set for this PERMISSION error -
   // so I'm probably never going to actually use this extended error reporting mechanism
   return 0;
}

int CryptInterface::GetErrorDetailSession(CRYPT_SESSION sess)
{
   int status;
   char limmessage[2048];
   int limlen = 2047;
   status = cryptGetAttributeString(sess, CRYPT_ATTRIBUTE_ERRORMESSAGE, limmessage, &limlen);
   limmessage[limlen] = '\0';
   fCryptCheckError(status);
   errprint(limmessage);
   return 0;
}

int CryptInterface::GetErrorDetailObject(CRYPT_HANDLE hand)
{
   int status;
   char limmessage[2048];
   int limlen = 2047;
   status = cryptGetAttributeString(hand, CRYPT_ATTRIBUTE_ERRORMESSAGE, limmessage, &limlen);
   limmessage[limlen] = '\0';
   fCryptCheckError(status);
   errprint(limmessage);
   return 0;
}

void CryptInterface::CheckCryptError(int status, const char *fpretty, int line)
{
   if (status == CRYPT_OK) return;
   switch (status)
   {
      case CRYPT_OK:
         /*errprintpd("No error.", fpretty, line); */break;
      case CRYPT_ERROR_PARAM1:
         errprintpd("There is a problem with the parameter 1.", fpretty, line); break;
      case CRYPT_ERROR_PARAM2:
         errprintpd("There is a problem with the parameter 2.", fpretty, line); break;
      case CRYPT_ERROR_PARAM3:
         errprintpd("There is a problem with the parameter 3.", fpretty, line); break;
      case CRYPT_ERROR_PARAM4:
         errprintpd("There is a problem with the parameter 4.", fpretty, line); break;
      case CRYPT_ERROR_PARAM5:
         errprintpd("There is a problem with the parameter 5.", fpretty, line); break;
      case CRYPT_ERROR_PARAM6:
         errprintpd("There is a problem with the parameter 6.", fpretty, line); break;
      case CRYPT_ERROR_PARAM7:
         errprintpd("There is a problem with the parameter 7.", fpretty, line); break;
      case CRYPT_ERROR_FAILED:
         errprintpd("Cryptlib operation failed.", fpretty, line); break;
      case CRYPT_ERROR_INITED:
         errprintpd("Already initialised.", fpretty, line); break;
      case CRYPT_ERROR_MEMORY:
         errprintpd("Not enough memory.", fpretty, line); break;
      case CRYPT_ERROR_NOSECURE:
         errprintpd("Cannot perform operation at security level requested.", fpretty, line); break;
      case CRYPT_ERROR_NOTINITED:
         errprintpd("Not initialised or not available.", fpretty, line); break;
      case CRYPT_ERROR_RANDOM:
         errprintpd("Not enough random data available.", fpretty, line); break;
      case CRYPT_ERROR_COMPLETE:
         errprintpd("Operation complete and cannot continue.", fpretty, line); break;
      case CRYPT_ERROR_INCOMPLETE:
         errprintpd("Operation incomplete.", fpretty, line); break;
      case CRYPT_ERROR_INVALID:
         errprintpd("Operation invalid - probably bad keys.", fpretty, line); break;
      case CRYPT_ERROR_NOTAVAIL:
         errprintpd("Operation unavailable.", fpretty, line); break;
      case CRYPT_ERROR_PERMISSION:
         errprintpd("Permission denied.", fpretty, line); break;
      case CRYPT_ERROR_SIGNALLED:
         errprintpd("Signalled.", fpretty, line); break;
      case CRYPT_ERROR_TIMEOUT:
         errprintpd("Operation timed out. Please try again.", fpretty, line); break;
      case CRYPT_ERROR_WRONGKEY:
         errprintpd("Wrong key.", fpretty, line); break;
      case CRYPT_ERROR_BADDATA:
         errprintpd("Corrupt or incomplete data.", fpretty, line); break;
      case CRYPT_ERROR_OVERFLOW:
         errprintpd("Data overflow.", fpretty, line); break;
      case CRYPT_ERROR_SIGNATURE:
         errprintpd("Signature or integrity check failure.", fpretty, line); break;
      case CRYPT_ERROR_UNDERFLOW:
         errprintpd("Insufficient data.", fpretty, line); break;
      case CRYPT_ERROR_DUPLICATE:
         errprintpd("Duplicated.", fpretty, line); break;
      case CRYPT_ERROR_NOTFOUND:
         errprintpd("Not found.", fpretty, line); break;
      case CRYPT_ERROR_OPEN:
         errprintpd("Could not be opened.", fpretty, line); break;
      case CRYPT_ERROR_READ:
         errprintpd("Could not be read.", fpretty, line); break;
      case CRYPT_ERROR_WRITE:
         errprintpd("Could not be written.", fpretty, line); break;
      case CRYPT_ENVELOPE_RESOURCE:
         errprintpd("Resources need to be added before this operation can continue.", fpretty, line); break;
      default:
         errprintpd("Unknown error.", fpretty, line); break;
   }
}
